<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: ipc::transport::struc::Struct_reader Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceipc.html">ipc</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1transport.html">transport</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1transport_1_1struc.html">struc</a></li><li class="navelem"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="classipc_1_1transport_1_1struc_1_1Struct__reader-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">ipc::transport::struc::Struct_reader Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>A documentation-only <em>concept</em> that is, conceptually, roughly what <code>capnp::MessageReader</code> is to <code>capnp::MessageBuilder</code>, to be used on an in-message serialized by a counterpart <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a>, having been transmitted over an IPC transmitter of blobs.  
 <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#details">More...</a></p>

<p><code>#include &lt;serializer.hpp&gt;</code></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html">Config</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Analogous to <a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__builder_1_1Config.html" title="Copy-ctible, copy-assignable, default-ctible type – informally, cheaply copyable and likely an aggreg...">Struct_builder::Config</a> but for deserialization.  <a href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a4dc980273439330d6d2359e764c7680a"><td class="memItemLeft" align="right" valign="top"><a id="a4dc980273439330d6d2359e764c7680a" name="a4dc980273439330d6d2359e764c7680a"></a>
&#160;</td><td class="memItemRight" valign="bottom"><b>Struct_reader</b> ()</td></tr>
<tr class="memdesc:a4dc980273439330d6d2359e764c7680a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Default ctor, leaving <code>*this</code> in a state only suitable for destruction or being moved-to. <br /></td></tr>
<tr class="separator:a4dc980273439330d6d2359e764c7680a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8395ee937193713e413c36c144ea9a30"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a8395ee937193713e413c36c144ea9a30">Struct_reader</a> (const <a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html">Config</a> &amp;config) <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a>(const <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;)=delete</td></tr>
<tr class="memdesc:a8395ee937193713e413c36c144ea9a30"><td class="mdescLeft">&#160;</td><td class="mdescRight">Main ctor, creating a new functioning builder according to the knobs in <code><a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html" title="Analogous to Struct_builder::Config but for deserialization.">Config</a> config</code> arg.  <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a8395ee937193713e413c36c144ea9a30">More...</a><br /></td></tr>
<tr class="separator:a8395ee937193713e413c36c144ea9a30"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6056a8c7cc94fd4ebe6f55054518cd4d"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a6056a8c7cc94fd4ebe6f55054518cd4d">Struct_reader</a> (<a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a6056a8c7cc94fd4ebe6f55054518cd4d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move-constructs <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted.  <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a6056a8c7cc94fd4ebe6f55054518cd4d">More...</a><br /></td></tr>
<tr class="separator:a6056a8c7cc94fd4ebe6f55054518cd4d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a66ccf2eda9b6302a98b0f326292332d2"><td class="memItemLeft" align="right" valign="top"><a id="a66ccf2eda9b6302a98b0f326292332d2" name="a66ccf2eda9b6302a98b0f326292332d2"></a>
&#160;</td><td class="memItemRight" valign="bottom"><b>~Struct_reader</b> ()</td></tr>
<tr class="memdesc:a66ccf2eda9b6302a98b0f326292332d2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destructor. Do not use the <code>Reader</code> <code><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a></code> or any copies thereof past this. <br /></td></tr>
<tr class="separator:a66ccf2eda9b6302a98b0f326292332d2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad82bfcf62d6e0e2c11266876dcc5714c"><td class="memItemLeft" align="right" valign="top"><a id="ad82bfcf62d6e0e2c11266876dcc5714c" name="ad82bfcf62d6e0e2c11266876dcc5714c"></a>
<a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><b>operator=</b> (const <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;)=delete</td></tr>
<tr class="memdesc:ad82bfcf62d6e0e2c11266876dcc5714c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Disallow copy assignment. <br /></td></tr>
<tr class="separator:ad82bfcf62d6e0e2c11266876dcc5714c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a89a0f2dd586d9c74c532a644b568d871"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a89a0f2dd586d9c74c532a644b568d871">operator=</a> (<a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a89a0f2dd586d9c74c532a644b568d871"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move-assigns <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted; or no-op if <code>&amp;src == this</code>.  <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a89a0f2dd586d9c74c532a644b568d871">More...</a><br /></td></tr>
<tr class="separator:a89a0f2dd586d9c74c532a644b568d871"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae450aff09cc9d71b75b382d59a9cfc23"><td class="memItemLeft" align="right" valign="top">flow::util::Blob *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23">add_serialization_segment</a> (size_t max_sz)</td></tr>
<tr class="memdesc:ae450aff09cc9d71b75b382d59a9cfc23"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prior to <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a> obtains a memory area <code>max_sz</code> bytes long into which the user may write-to until the next <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>, <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a>, or dtor call (whichever happens first); returns a pointer to that area as described by the pointed-to <code>Blob</code>'s [<code>begin()</code>, <code>end()</code>) range.  <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23">More...</a><br /></td></tr>
<tr class="separator:ae450aff09cc9d71b75b382d59a9cfc23"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a95576f8cd8ad45a720276bd074cea4f2"><td class="memTemplParams" colspan="2">template&lt;typename Struct &gt; </td></tr>
<tr class="memitem:a95576f8cd8ad45a720276bd074cea4f2"><td class="memTemplItemLeft" align="right" valign="top">Struct::Reader&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2">deserialization</a> (<a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code=0)</td></tr>
<tr class="memdesc:a95576f8cd8ad45a720276bd074cea4f2"><td class="mdescLeft">&#160;</td><td class="mdescRight">After all serialization segments have been acquired in RAM via <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> and finalized via begin-end-range adjustment, this returns a reference to the reader object whose capnp-generated accessors can read the structured contents of <code>*this</code>.  <a href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2">More...</a><br /></td></tr>
<tr class="separator:a95576f8cd8ad45a720276bd074cea4f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >A documentation-only <em>concept</em> that is, conceptually, roughly what <code>capnp::MessageReader</code> is to <code>capnp::MessageBuilder</code>, to be used on an in-message serialized by a counterpart <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a>, having been transmitted over an IPC transmitter of blobs. </p>
<p >The following discussion assumes understanding of <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> (see its doc header).</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a>, the counterpart concept.</dd></dl>
<p>Here is how a <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> is used (in order):</p><ul>
<li>Suppose the counterpart <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> was used as documented in its doc header, for a given out-message.</li>
<li>Construct a matching <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> on the other side.<ul>
<li>See also <a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html" title="Analogous to Struct_builder::Config but for deserialization.">Struct_reader::Config</a>.</li>
</ul>
</li>
<li>Call <code>add_serialization_segment(M)</code>, where M is the maximum number of bytes the next blob-read out of the transport might return when reading the next serialization segment produced by <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a>. (M, in practice, is limited by at least the transport and how it is used; and the segment sizes the <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> impl in practice produces.)<ul>
<li><code>*this</code> shall obtain an area in memory at least M bytes long into which it is guaranteed safe for for the user to direct-write, until the next <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>, <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a>, or dtor call (whichever happens earliest).</li>
<li><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> shall return a <em>pointer</em> to a <code>flow::util::Blob</code> whose [<code>begin()</code>, <code>end()</code>) range represents that memory area (with <code>.size()</code> equal to M).<ul>
<li>If the impl determines that its (not specified by this concept) memory acquisition algorithm is incapable of obtaining M bytes, it shall return null. The user must be ready for this eventuality.</li>
</ul>
</li>
</ul>
</li>
<li>Copy the next segment's contents out of the transport into the aforementioned <code>Blob</code>.</li>
<li>Use <code>flow::util::Blob::resize()</code> (or similar methods that invoke it, notably <code>start_past_prefix_inc()</code>) to modify the [<code>begin()</code>, <code>end()</code>) range such that it stores the exact contents of the segment.<ul>
<li>In practice: It at least means <code>resize(K)</code>, where <code>K &lt;= M</code>, to mark the actual size of the received segment, since M is the <em>max</em> possible size. So the garbage area into which no bytes were written must be excluded.</li>
<li>It may also mean sliding around <code>begin()</code> and/or <code>end()</code> to deliberately exclude any framing information used by the user's protocol when transmitting segments. This is important to maintain zero-copy perf.</li>
<li>Behavior is undefined if the user calls <code>.make_zero()</code> on that blob. Only <code>.resize()</code> (and its convenience wrappers like <code>start_past_prefix_inc()</code>) may be invoked.</li>
</ul>
</li>
<li>If and only if the serialization produced by the <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> consists of 2+ segments: Repeat the previous 3 bullet points, in order, for each of the additional 1+ segments.</li>
<li>Lastly execute <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">Struct_reader::deserialization&lt;Struct&gt;()</a> (at most once) to obtain obtain a capnp-generated <code>Struct::Reader</code>.<ul>
<li>Access the structured contents that the other side had mutated-in via the latter-returned <code>Struct::Reader</code>.</li>
</ul>
</li>
<li>Finally, the <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> <code>*this</code> can be destroyed.</li>
</ul>
<h3>Copying versus zero-copy</h3>
<p >See the same-named section of <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> doc header. Similar concerns apply here. Generally speaking, how a <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> works is dictated by the decisions made for its <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> counterpart.</p>
<h3>Allocation and perf</h3>
<p >See the same-named section of <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> doc header first. Similar concerns apply here, but actually the decision about how to obtain memory areas as returned by <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> in <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> can be 100% decoupled from how <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a> counterpart acquires memory. E.g., the builder might allocate from heap, while the reader might allocate from a single buffer allocated by <code><a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html" title="Analogous to Struct_builder::Config but for deserialization.">Config</a></code>, just because the latter has a single-threaded receiver setup, while the former involves multi-threaded concurrently-sending chaos. One can mix and match: the outer serialization is always copied-into the transport (then destroyed) on the builder side and copied-from the transport on the reader side. The manner in which memory is acquired before each write (builder case) or before each read (reader case) can be determined by the algorithm used by the application on each side.</p>
<h3>Why is <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> designed this way?</h3>
<p >It might seem unnecessarily complex: user must call <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>, then write to that <code>Blob</code> and adjust its range. They could conceivably just allocate their own <code>Blob</code> and then <code>move()</code> it into <code>*this</code> via a single, simpler <code>add_serialization_segment(Blob&amp;&amp;)</code> call. So why is it done the former way?</p>
<p >Answer: It's to support the possibilities discussed in the "Allocation and perf" section above. <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> places the responsibility of obtaining target memory for the blob-read on the <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html" title="A documentation-only concept that is, conceptually, roughly what capnp::MessageReader is to capnp::Me...">Struct_reader</a> concept impl. Hence different concept impls can be swapped in for different perf/use-case trade-offs. One would use a pool &ndash; another would use the heap... etc. </p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a8395ee937193713e413c36c144ea9a30" name="a8395ee937193713e413c36c144ea9a30"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8395ee937193713e413c36c144ea9a30">&#9670;&nbsp;</a></span>Struct_reader() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">ipc::transport::struc::Struct_reader::Struct_reader </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html">Config</a> &amp;&#160;</td>
          <td class="paramname"><em>config</em></td><td>)</td>
          <td> const &amp;</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span><span class="mlabel">delete</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Main ctor, creating a new functioning builder according to the knobs in <code><a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html" title="Analogous to Struct_builder::Config but for deserialization.">Config</a> config</code> arg. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">config</td><td><a class="el" href="structipc_1_1transport_1_1struc_1_1Struct__reader_1_1Config.html" title="Analogous to Struct_builder::Config but for deserialization.">Struct_reader::Config</a> storing the knobs controlling how <code>*this</code> will work. Disallow copy construction. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a6056a8c7cc94fd4ebe6f55054518cd4d" name="a6056a8c7cc94fd4ebe6f55054518cd4d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6056a8c7cc94fd4ebe6f55054518cd4d">&#9670;&nbsp;</a></span>Struct_reader() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">ipc::transport::struc::Struct_reader::Struct_reader </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Move-constructs <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Moved-from object that becomes as-if default-cted. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="ae450aff09cc9d71b75b382d59a9cfc23" name="ae450aff09cc9d71b75b382d59a9cfc23"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae450aff09cc9d71b75b382d59a9cfc23">&#9670;&nbsp;</a></span>add_serialization_segment()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">flow::util::Blob * ipc::transport::struc::Struct_reader::add_serialization_segment </td>
          <td>(</td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>max_sz</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prior to <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a> obtains a memory area <code>max_sz</code> bytes long into which the user may write-to until the next <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>, <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a>, or dtor call (whichever happens first); returns a pointer to that area as described by the pointed-to <code>Blob</code>'s [<code>begin()</code>, <code>end()</code>) range. </p>
<p >If the concept impl decides <code>max_sz</code> bytes are not available, returns null. <code>*this</code> shall not be used subsequent to such an eventuality.</p>
<p >To use <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a> subsequently, you must:</p><ul>
<li>call this at least once (successfully);</li>
<li>call this (N - 1) more times (successfully), where N is the number of segments produced by the counterpart <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__builder.html" title="A documentation-only concept defining the behavior of an object capable of zero-copy-serializing,...">Struct_builder</a>.<ul>
<li>So N &gt;= 1 by definition.</li>
</ul>
</li>
</ul>
<p >The required sequence for each in-segment is:</p><ul>
<li>Call <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>, which yields pointer to a <code>Blob</code>.</li>
<li>Write segment serialization into (some subrange of) that <code>Blob</code>'s [<code>begin()</code>, <code>end()</code>) range (presumably directly out of the transport).</li>
<li>Adjust said <code>Blob</code>'s [<code>begin()</code>, <code>end()</code>) range to contain exactly the serialization segment.<ul>
<li>You may use <code>.resize()</code> or its convenience wrappers <code>.start_past_prefix()</code> and <code>.start_past_prefix_inc()</code>. Use these to (1) mark the actual segment's size (which may well be &lt; <code>max_sz</code>) and (2) discard any framing data that came in together with the segment serialization.</li>
<li>You may not <code>.make_zero()</code> (or behavior is undefined).</li>
<li>You may not use <code>.resize()</code> and friends to cause <code>begin()</code> to go left or <code>end()</code> to go right. They can only remain unchanged or travel right and left respectively (the range's edges cannot "extend" past the original range provided).</li>
</ul>
</li>
</ul>
<p >After these steps, either <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> again (if more segments are forthcoming), or call <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a> (to use the structured data), or invoke dtor (if <code>*this</code> is no longer of interest).</p>
<h3>Alignment</h3>
<p >The returned <code>Blob</code>'s begin-to-end range shall be word-aligned, meaning <code>.const_data()</code> shall be on a word boundary, meaning the numeric value thereof shall be a multiple of <code>sizeof(void*)</code>. This is the guarantee of <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a>.</p>
<p >Accordingly, any <code>.resize()</code> (etc.) done on the returned <code>Blob</code> by the user <em>must</em> result in a <code>.const_data()</code> (a/k/a <code>.begin()</code>) that is <em>still</em> word-aligned by the same definition. Informally there are ~2 ways to guarantee this on the user's part:</p><ul>
<li>Just don't change <code>begin()</code> (do not use prefix frame data; you may use postfix frame data instead). Or:</li>
<li>If you require frame data to live in front of the segment, in your protocol ensure that the size of such frame data is a multiple of <code>sizeof(void*)</code>.</li>
</ul>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">max_sz</td><td><code>Blob</code> to which the returned pointer points shall have <code>.size() == max_sz</code>. (It may have equal or larger <code>.capacity()</code>.) See above. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to the <code>Blob</code> inside which to place, subsequently, the next segment's contents. See above. </dd></dl>

</div>
</div>
<a id="a95576f8cd8ad45a720276bd074cea4f2" name="a95576f8cd8ad45a720276bd074cea4f2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a95576f8cd8ad45a720276bd074cea4f2">&#9670;&nbsp;</a></span>deserialization()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Struct &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">Struct::Reader ipc::transport::struc::Struct_reader::deserialization </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>0</code></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>After all serialization segments have been acquired in RAM via <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> and finalized via begin-end-range adjustment, this returns a reference to the reader object whose capnp-generated accessors can read the structured contents of <code>*this</code>. </p>
<p >Behavior is undefined if this is called before all <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> calls have been made (and they must have been successful). Behavior is undefined if <a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> is called after this is called.</p>
<p ><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#a95576f8cd8ad45a720276bd074cea4f2" title="After all serialization segments have been acquired in RAM via add_serialization_segment() and finali...">deserialization()</a> shall be called no more than once.</p>
<p >The returned <code>Reader</code> shall remain valid until <code>*this</code> is destroyed. (Therefore any copies thereof shall also be valid in the same time frame. However there is no perf benefit to making such copies, and there is likely a small penalty to doing so.)</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Struct</td><td>Same meaning as in the vanilla capnp use of <code>MessageReader::getRoot&lt;Struct&gt;()</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: <a class="el" href="namespaceipc_1_1transport_1_1struc_1_1error.html#a990b9ff850cf9aaf354efdd07d86a71da0051bcafea044bc07af9f4aca02f0e3b" title="Structured message deserialization: Tried to deserialize without enough input segments (e....">error::Code::S_DESERIALIZE_FAILED_INSUFFICIENT_SEGMENTS</a> (<a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> was called an insufficient number of times; in particular 0 times always triggers this); <a class="el" href="namespaceipc_1_1transport_1_1struc_1_1error.html#a990b9ff850cf9aaf354efdd07d86a71dae309ae915136b629fafaec158040a406" title="Structured message deserialization: An input segment is not aligned as required.">error::Code::S_DESERIALIZE_FAILED_SEGMENT_MISALIGNED</a> (<a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html#ae450aff09cc9d71b75b382d59a9cfc23" title="Prior to deserialization() obtains a memory area max_sz bytes long into which the user may write-to u...">add_serialization_segment()</a> was called with a segment that starts at a misaligned address); implementation may also emit other errors. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. If and only if <code>err_code</code> is non-null, and truthy <code>*err_code</code> is emitted, a useless (default-cted) <code>Reader</code> is returned. </dd></dl>

</div>
</div>
<a id="a89a0f2dd586d9c74c532a644b568d871" name="a89a0f2dd586d9c74c532a644b568d871"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a89a0f2dd586d9c74c532a644b568d871">&#9670;&nbsp;</a></span>operator=()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp; ipc::transport::struc::Struct_reader::operator= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classipc_1_1transport_1_1struc_1_1Struct__reader.html">Struct_reader</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Move-assigns <code>*this</code> to be equal to <code>src</code>, while <code>src</code> becomes as-if defaulted-cted; or no-op if <code>&amp;src == this</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Moved-from object that becomes as-if default-cted, unless it is <code>*this</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>*this</code>. </dd></dl>

</div>
</div>
<hr/>The documentation for this class was generated from the following file:<ul>
<li>transport/struc/<a class="el" href="ipc__transport__structured_2src_2ipc_2transport_2struc_2serializer_8hpp.html">serializer.hpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:36 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
